#include "oled.h"
#include "font.h"
#include "delay.h"
#include "string.h"
#include <stdio.h>

extern uint8_t esp8266_connect_flag;//wifi连接服务器成功标志


/*   
	标志按键状态
	0：待机
	1：编程模式
	2：选择功能模式
	3: 修改管理员密钥时，输入新密钥数据状态(管理员密钥)
	4: 修改管理员密钥时，输入新密钥数据状态(用户密钥)
	
*/
uint8_t si12_schema_flag = 0;

/*   
	标志rfid状态
	0：读卡模式
	1：加卡模式
	2：减卡模式
	3: 韦根26
	
*/
uint8_t rfid_schema_flag = 0;

/*   
	标志指纹状态
	0：验证模式
	1：添加指纹模式
	2：减少指纹模式

*/
uint8_t as608_schema_flag = 0;

extern uint8_t button_buf[8]; //按键数据
extern uint8_t button_buf_len;//按键数据长度

uint8_t OLED_GRAM[144][8];
//写cs
void oled_write_dc(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_0, (BitAction)BitValue);
}

//写res
void oled_write_res(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_1, (BitAction)BitValue);
}

//oled 初始化
void oled_init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; 
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	oled_write_dc(1);
	//复位
	oled_write_res(1);
	delay_ms(50);
	oled_write_res(0);
	delay_ms(50);
	oled_write_res(1);
	
	oled_spi_init();
	
	oled_writecmd(0xAE);//--turn off oled panel
	oled_writecmd(0x00);//---set low column address
	oled_writecmd(0x10);//---set high column address
	oled_writecmd(0x40);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
	oled_writecmd(0x81);//--set contrast control register
	oled_writecmd(0xCF);// Set SEG Output Current Brightness
	oled_writecmd(0xA1);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
	oled_writecmd(0xC8);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
	oled_writecmd(0xA6);//--set normal display
	oled_writecmd(0xA8);//--set multiplex ratio(1 to 64)
	oled_writecmd(0x3f);//--1/64 duty
	oled_writecmd(0xD3);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
	oled_writecmd(0x00);//-not offset
	oled_writecmd(0xd5);//--set display clock divide ratio/oscillator frequency
	oled_writecmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
	oled_writecmd(0xD9);//--set pre-charge period
	oled_writecmd(0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	oled_writecmd(0xDA);//--set com pins hardware configuration
	oled_writecmd(0x12);
	oled_writecmd(0xDB);//--set vcomh
	oled_writecmd(0x40);//Set VCOM Deselect Level
	oled_writecmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
	oled_writecmd(0x02);//
	oled_writecmd(0x8D);//--set Charge Pump enable/disable
	oled_writecmd(0x14);//--set(0x10) disable
	oled_writecmd(0xA4);// Disable Entire Display On (0xa4/0xa5)
	oled_writecmd(0xA6);// Disable Inverse Display On (0xa6/a7) 
	oled_writecmd(0xAF);
        
  OLED_Clear();                //OLED清屏
  
	OLED_ShowString(1,1,"KEY:");
	oled_si12_mode(0);
	oled_rfid_mode(0);
}

//写命令
void oled_writecmd(uint8_t command)
{
	oled_spi_write_ss(0);
	oled_write_dc(0);
	oled_spi_swapbyte(command);
	oled_spi_write_ss(1);
}

//写数据
void oled_wirtedata(uint8_t data)
{
	oled_spi_write_ss(0);
	oled_write_dc(1);
	oled_spi_swapbyte(data);
	oled_spi_write_ss(1);
}




/**
  * @brief  OLED清屏
  * @param  无
  * @retval 无
  */
void OLED_Clear(void)
{  
  uint8_t i,n;
	for(i=0;i<8;i++)
	{
	   for(n=0;n<128;n++)
			{
			 OLED_GRAM[n][i]=0;//清除所有数据
			}
  }
	OLED_Refresh();//更新显示
}


/**
  * @brief  OLED显示一个字符
  * @param  Line 行位置，范围：0~64
  * @param  Column 列位置，范围：0~128
  * @param  Char 要显示的一个字符，范围：ASCII可见字符
  * @retval 无 16X16字体
  */
void OLED_ShowChar(uint8_t x, uint8_t y, char Char)
{          
	uint8_t i,m,temp,size2,chr1;
	uint8_t y0=y;
	uint8_t size1 = STR_SIZE;
	size2=(size1/8+((size1%8)?1:0))*(size1/2);  //得到字体一个字符对应点阵集所占的字节数
	chr1=Char-' ';  //计算偏移后的值
	for(i=0;i<size2;i++)
	{
		if(size1==STR_SIZE)
    {
			temp=OLED_F8x16[chr1][i];
		} //调用1608字体
		else return;
		for(m=0;m<8;m++)           //写入数据
		{
			if(temp&0x80)OLED_DrawPoint(x,y);
			else OLED_ClearPoint(x,y);
			temp<<=1;
			y++;
			if((y-y0)==size1)
			{
				y=y0;
				x++;
				break;
      }
		}
  }
}





void OLED_CloseRoll(void)
{
    //以下添加水平滚动效果
    oled_writecmd(0x2e);//关滚动
    oled_writecmd(0x2a);//29向右，2a向左
    oled_writecmd(0x00);//A:空字节
    oled_writecmd(0x00);//B:水平起始页
    oled_writecmd(0x07);//C:水平滚动速度
    oled_writecmd(0x07);//D:水平结束页
    oled_writecmd(0x00);//E:每次垂直滚动位移
//    oled_writecmd(0x2f);//开滚动
}
void OLED_OpenRoll(void)
{
    //以下添加水平滚动效果
    oled_writecmd(0x2f);//开滚动
}

//画点
//x:0~127
//y:0~63
void OLED_DrawPoint(uint8_t x,uint8_t y)
{
	uint8_t i,m,n;
	i=y/8;
	m=y%8;
	n=1<<m;
	OLED_GRAM[x][i]|=n;
}


//清除一个点
//x:0~127
//y:0~63
void OLED_ClearPoint(uint8_t x,uint8_t y)
{
	uint8_t i,m,n;
	i=y/8;
	m=y%8;
	n=1<<m;
	OLED_GRAM[x][i]=~OLED_GRAM[x][i];
	OLED_GRAM[x][i]|=n;
	OLED_GRAM[x][i]=~OLED_GRAM[x][i];
}

//更新显存到OLED	
void OLED_Refresh(void)
{
	u8 i,n;
	for(i=0;i<8;i++)
	{
	   oled_writecmd(0xb0+i); //设置行起始地址
	   oled_writecmd(0x00);   //设置低列起始地址
	   oled_writecmd(0x10);   //设置高列起始地址
	   for(n=0;n<128;n++)
		 oled_wirtedata(OLED_GRAM[n][i]);
  }
}

/**
	* @brief  OLED显示字符串
	* @param  Line 行位置，范围：1~4（超过范围舍弃）
	* @param  Column 列位置，范围：1~16（超过范围换行，超出屏幕舍弃）
  * @param  string 要显示的一个字符，范围：ASCII可见字符
  * @retval 无 16X16字体
  */
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String)
{
	uint8_t x,y;
	if(Line<1||Line>8)
	{
		return;
	}

	while(*String)
	{
		y = (Line-1) *STR_SIZE;
		x = (Column-1)*(STR_SIZE/2);
		OLED_ShowChar(x,y,*String);
		if(Column<16)
		{
			Column++;
		}
		else
		{
			if(Line<4)
			{
				Column = 1;
				Line++;
			}
			else
			{
				break;
			}
		}
		String++;
	}
	OLED_Refresh();
}

//在三行显示si12模式
void oled_si12_mode(uint8_t mode)
{
	char temp[17]={"key:"};
//	uint8_t i;
	switch(mode)
	{
		case 0://待机模式
		{
			memset(button_buf,' ',8);
			button_buf_len = 0;
			memset(&temp[4],' ',12);
			OLED_ShowString(1,1,temp);
			OLED_ShowString(3,1,"    standby     ");
			break;
		}
		case 1://编程模式
		{
			OLED_ShowString(3,1,"     input      ");
			break;
		}
		case 2://选择模式
		{
			memset(button_buf,' ',8);
			button_buf_len = 0;
			memset(&temp[4],' ',12);
			OLED_ShowString(1,1,temp);
			OLED_ShowString(3,1,"     select     ");
			break;
		}
		case 3://等待新密钥输入模式
		case 4:
		{
			OLED_ShowString(3,1,"    new key     ");
			break;
		}
	}
}
//在四行显示rfid模式
void oled_rfid_mode(uint8_t mode)
{
	switch(mode)
	{
		case 0://读卡模式
		{
			OLED_ShowString(4,1,"      RFID      ");
			break;
		}
		case 1://加卡模式
		{
			OLED_ShowString(4,1,"      add       ");
			break;
		}
		case 2://减卡模式
		{
			OLED_ShowString(4,1,"    subtract    ");
			break;
		}
		case 3://韦根26
		{
			OLED_ShowString(4,1,"       26       ");
			break;
		}
	}
}


//在第二行显示as608和wifi是否连接
void oled_as608_mode(uint8_t mode)
{
  char str[16];
  switch(mode)
	{
		case 0://普通等待指纹模式
		{
      sprintf(str,"%c AS608:        ",(esp8266_connect_flag==1)?'*':' ');
			OLED_ShowString(2,1,str);
			break;
		}
		case 1://加模式
		{
			sprintf(str,"%c AS608:ADD     ",(esp8266_connect_flag==1)?'*':' ');
      OLED_ShowString(2,1,str);
			break;
		}
		case 2://减模式
		{
      sprintf(str,"%c AS608:DELETE  ",(esp8266_connect_flag==1)?'*':' ');
			OLED_ShowString(2,1,str);
			break;
		}
	}
}

void oled_updata_key(void)
{
	char temp[17]={"key:"};
	uint8_t i;
	memset(&temp[4],' ',12);
	memcpy(&temp[4],button_buf,button_buf_len);
	for(i=0;i<button_buf_len;i++)
	{
		temp[i+4] += 48; 
	}
	OLED_ShowString(1,1,temp);
}
